﻿using System;
using System.Windows.Media;

namespace ZOIL.Framework.Presentation
{
    /// <summary>
    /// A static class that encapsulates the CompositionTarget.Rendering event.
    /// Since this event is often fired more than once per time frame, we can skip certain calls
    /// See http://evanl.wordpress.com/2009/12/06/efficient-optimal-per-frame-eventing-in-wpf/ for details
    /// </summary>
    public static class CompositionTargetExtension
    {
        /// <summary>
        /// the timeSpan of the last frame call
        /// </summary>
        private static TimeSpan _last = TimeSpan.Zero;
        
        /// <summary>
        /// internal event which is raised only once per time frame
        /// </summary>
        private static event EventHandler<RenderingEventArgs> _frameUpdating;
        
        /// <summary>
        /// public dummy event that manages registering of CompositionTarget.Rendering event.
        /// </summary>
        public static event EventHandler<RenderingEventArgs> FrameUpdating
        {
            add
            {
                if (_frameUpdating == null)
                    CompositionTarget.Rendering += OnCompositionTargetRendering;

                _frameUpdating += value;
            }

            remove
            {
                _frameUpdating -= value;
                if (_frameUpdating == null)
                    CompositionTarget.Rendering -= OnCompositionTargetRendering;
            }
        }

        /// <summary>
        /// takes care that the _FrameUpdating event is only called once per time frame
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnCompositionTargetRendering(object sender, EventArgs e)
        {
            RenderingEventArgs args = (RenderingEventArgs)e;
            if (args.RenderingTime == _last) return;

            _last = args.RenderingTime;
            _frameUpdating(sender, args);
        }
    }
}
